﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Input;
using System.Runtime.InteropServices;

namespace InputEmulator
{
    class Program
    {
        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct tagINPUT
        {
            /// DWORD->unsigned int
            public uint type;

            /// Anonymous_dccf47da_5155_438b_92bc_41adbefe840c
            public Anonymous_dccf47da_5155_438b_92bc_41adbefe840c Union1;
        }

        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)]
        public struct Anonymous_dccf47da_5155_438b_92bc_41adbefe840c
        {
            /// MOUSEINPUT->tagMOUSEINPUT
            [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
            public tagMOUSEINPUT mi;

            /// KEYBDINPUT->tagKEYBDINPUT
            [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
            public tagKEYBDINPUT ki;

            /// HARDWAREINPUT->tagHARDWAREINPUT
            [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
            public tagHARDWAREINPUT hi;
        }

        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct tagMOUSEINPUT
        {
            /// LONG->int
            public int dx;

            /// LONG->int
            public int dy;

            /// DWORD->unsigned int
            public uint mouseData;

            /// DWORD->unsigned int
            public uint dwFlags;

            /// DWORD->unsigned int
            public uint time;

            /// ULONG_PTR->unsigned int
            public uint dwExtraInfo;
        }

        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct tagKEYBDINPUT
        {
            /// WORD->unsigned short
            public ushort wVk;

            /// WORD->unsigned short
            public ushort wScan;

            /// DWORD->unsigned int
            public uint dwFlags;

            /// DWORD->unsigned int
            public uint time;

            /// ULONG_PTR->unsigned int
            public uint dwExtraInfo;
        }

        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct tagHARDWAREINPUT
        {
            /// DWORD->unsigned int
            public uint uMsg;

            /// WORD->unsigned short
            public ushort wParamL;

            /// WORD->unsigned short
            public ushort wParamH;
        }

        /// Return Type: UINT->unsigned int
        ///cInputs: UINT->unsigned int
        ///pInputs: LPINPUT->tagINPUT*
        ///cbSize: int
        [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "SendInput")]
        public static extern uint SendInput(uint cInputs, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPArray, ArraySubType = System.Runtime.InteropServices.UnmanagedType.Struct, SizeParamIndex = 0)] tagINPUT[] pInputs, int cbSize);

        public static void pressCtrlShiftSpace()
        {
            //VK codes - http://msdn.microsoft.com/en-us/library/dd375731
            tagINPUT[] InputData = new tagINPUT[6];

            //press ctrl key
            InputData[0].type = 1; //INPUT_KEYBOARD
            InputData[0].Union1.ki.wVk = 0x11;
            InputData[0].Union1.ki.wScan = 0;

            //press shift key
            InputData[1].type = 1; //INPUT_KEYBOARD
            InputData[1].Union1.ki.wVk = 0x10;
            InputData[1].Union1.ki.wScan = 0;

            //press space key
            InputData[2].type = 1; //INPUT_KEYBOARD
            InputData[2].Union1.ki.wVk = 0x20;
            InputData[2].Union1.ki.wScan = 0;

            //release ctrl key
            InputData[3].type = 1; //INPUT_KEYBOARD
            InputData[3].Union1.ki.wVk = 0x11;
            InputData[3].Union1.ki.wScan = 0;
            InputData[3].Union1.ki.dwFlags = 0x0002;

            //release shift key
            InputData[4].type = 1; //INPUT_KEYBOARD
            InputData[4].Union1.ki.wVk = 0x10;
            InputData[4].Union1.ki.wScan = 0;
            InputData[4].Union1.ki.dwFlags = 0x0002;

            //release space key
            InputData[5].type = 1; //INPUT_KEYBOARD
            InputData[5].Union1.ki.wVk = 0x20;
            InputData[5].Union1.ki.wScan = 0;
            InputData[5].Union1.ki.dwFlags = 0x0002;

            //send key
            if (SendInput(6, InputData, Marshal.SizeOf(InputData[0])) == 0)
            {
                Console.WriteLine("SendInput failed with code: " + Marshal.GetLastWin32Error().ToString());
            }
        }

        public static void pressCtrlShiftS()
        {
            //VK codes - http://msdn.microsoft.com/en-us/library/dd375731

            tagINPUT[] InputData = new tagINPUT[6];

            //press ctrl key
            InputData[0].type = 1; //INPUT_KEYBOARD
            InputData[0].Union1.ki.wVk = 0x11;
            InputData[0].Union1.ki.wScan = 0;

            //press shift key
            InputData[1].type = 1; //INPUT_KEYBOARD
            InputData[1].Union1.ki.wVk = 0x10;
            InputData[1].Union1.ki.wScan = 0;

            //press S key
            InputData[2].type = 1; //INPUT_KEYBOARD
            InputData[2].Union1.ki.wVk = 0x53;
            InputData[2].Union1.ki.wScan = 0;

            //release ctrl key
            InputData[3].type = 1; //INPUT_KEYBOARD
            InputData[3].Union1.ki.wVk = 0x11;
            InputData[3].Union1.ki.wScan = 0;
            InputData[3].Union1.ki.dwFlags = 0x0002;

            //release shift key
            InputData[4].type = 1; //INPUT_KEYBOARD
            InputData[4].Union1.ki.wVk = 0x10;
            InputData[4].Union1.ki.wScan = 0;
            InputData[4].Union1.ki.dwFlags = 0x0002;

            //release S key
            InputData[5].type = 1; //INPUT_KEYBOARD
            InputData[5].Union1.ki.wVk = 0x53;
            InputData[5].Union1.ki.wScan = 0;
            InputData[5].Union1.ki.dwFlags = 0x0002;

            //send key
            if (SendInput(6, InputData, Marshal.SizeOf(InputData[0])) == 0)
            {
                Console.WriteLine("SendInput failed with code: " + Marshal.GetLastWin32Error().ToString());
            }
        }

        static void Main(string[] args)
        {
            Random r = new Random();

            pressCtrlShiftS();

            while (true)
            {
                int sleepDuration = (30 + r.Next(8)) * 1000;
                Thread.Sleep(sleepDuration);

                int branch = r.Next(2);
                if (branch == 0)
                {
                    pressCtrlShiftSpace();
                }
                else
                {
                    pressCtrlShiftS();

                    int waitDuration = r.Next(4) * 1000;
                    Thread.Sleep(waitDuration);

                    pressCtrlShiftS();
                }
            }
        }
    }
}
